﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Timers;

namespace DotNetMigrations
{
	public class Database
	{
		/// <summary>
		/// Migrate to the most recent schema available.
		/// </summary>
		public static bool Migrate()
		{
			long targetVersion = MigrationScript.GetLatestMigrationVersion();
			return Migrate(targetVersion);
		}

		/// <summary>
		/// Migrate to a specific version of the schema.
		/// </summary>
		public static bool Migrate(long targetVersion)
		{
		    Stopwatch timer = new Stopwatch();
		    timer.Start();

			long currentVersion = SchemaInfoTable.GetSchemaVersion();
			Output.Write("Database at version " + currentVersion);

			if (currentVersion == targetVersion)
				return true;

		    bool isTearDown = false;
		    bool isSetup = false;

			List<string> scripts = new List<string>();

            if (currentVersion > targetVersion)
            {
                isTearDown = true;
                scripts = MigrationScript.GetTearDownScripts(currentVersion, targetVersion);
            }
            if (currentVersion < targetVersion)
            {
                isSetup = true;
                scripts = MigrationScript.GetSetupScripts(currentVersion, targetVersion);
            }

		    bool successful = false;
			if (scripts != null && scripts.Count > 0)
				successful = DAL.ExecuteScripts(scripts);
			if (successful)
			{
				if (isTearDown) { SchemaInfoTable.TearDownVersion(targetVersion); }
                if (isSetup)
                {
                    List<long> vers = SchemaInfoTable.GetVersionList(currentVersion, targetVersion);
                    SchemaInfoTable.SetupVersion(vers);
                }

				Output.Write("Migration completed");
			}
			else
			{
				Output.Write("Migration failed");
			}

			currentVersion = SchemaInfoTable.GetSchemaVersion();
			Output.Write("Database at version " + currentVersion);

            timer.Stop();
		    decimal seconds = decimal.Divide(timer.ElapsedMilliseconds, 1000);
            Output.WriteVerbose("-> " + seconds.ToString("0.0000s"));
			
			return successful;
		}
	}
}
